import re
import hashlib
from muddery.commands.unloggedin import CmdUnconnectedCreate
from muddery.commands.unloggedin import CmdUnconnectedConnect, _throttle
from muddery.commands.unloggedin import CmdUnconnectedQuit
from muddery.commands.unloggedin import CmdUnconnectedLook
from muddery.utils.game_settings import GAME_SETTINGS
from evennia.accounts.models import AccountDB
from evennia.utils import logger
from evennia.commands.command import Command
from utils.builds import create_player


class CmdUnLoginConnect(CmdUnconnectedConnect):
    """
    用于链接游戏

    用法:
        {'cmd': 'connect',
         'args':{
                'playername': <playername>,
                'password': <password>
                }
        }
    """
    key = 'connect'
    # 设置权限:所有人都可用
    locks = 'cmd:all()'

    def func(self):
        session = self.caller
        args = self.args
        # 定义输入错误后,多长时间可以输入
        timeout = 5*60

        try:
            playername = args['playername']
            password = args['password']

        except Exception:
            msg = '缺少关键参数<playername>, <password>, \n请检查后重试'
            session.msg({'is_login': False, 'msg': msg})
            return

        # 检查密码是否输入错误5次以上,如果输出错误达到5次,10分钟后在尝试输入
        if _throttle(session, maxlim=5, timeout=timeout):
            msg = '连续5次输入错误,请过{}分钟后在尝试'.format(timeout)
            session.msg({'is_login': False, 'msg': msg})
            return

        player = AccountDB.objects.get_account_from_name(playername)
        pswd = None
        if player:
            pswd = player.check_password(password)

        if not (player and pswd):
            msg = '账户密码错误, 请核对后查看'
            session.msg({'is_login': False, 'msg': msg})
            return

        msg = '登入成功'
        session.msg({'is_login': True, 'msg': msg, 'dbref': player.dbref})
        session.sessionhandler.login(session, player)


class CmdUnLoginCreateAccount(CmdUnconnectedCreate):
    """
    创建新用户账户

    用法:
        {
        'cmd': 'create',
        'args':{
                'playername': <playername>,
                'password': <password>,
                'connect': <是否直接登入用户>
                }
        }
    """

    key = 'create'
    # 命令权限
    locks = 'cmd:all()'

    def func(self):
        caller = self.caller
        args = self.args

        try:
            playername = args['playername']
            password = args['password']
            connect = args['connect']
        except Exception:
            caller.msg({'is_create': False, 'msg': self.__doc__})
            return

        if not re.findall('^[\w. @+-]+$', playername) or not (0 < len(playername) <= 16):
            msg = "账户只允许创建小于16位和<@/./+/-/_>符号"
            caller.msg({'is_create': False, 'msg': msg})
            return

        if AccountDB.objects.filter(username_iexact=playername):
            msg = '用户名已经存在,请更换'
            caller.msg({'is_create': False, 'msg': msg})
            return

        if not re.findall('^[\w. @+-]+$', password) or not (5 < len(password) <= 12):
            msg = '密码5-12位数, 且不允许设置特殊字符'
            caller.msg({'is_create': False, 'msg': msg})
            return

        if args:
            if args not in ['True', 'False']:
                msg = '只能填写为 <True> or <False>'
                caller.msg({'is_create': False, 'msg': msg})
                return

        new_player = None
        try:
            new_player = create_player(playername, password)

        except Exception as e:
            caller.msg({'is_create': False, 'msg': e})
            logger.log_tracemsg()

        if new_player:
            if connect:
                caller.msg({'is_create': True, 'data':
                            {'account': playername, 'dbref': new_player.dbref},
                            'is_login': True})
                caller.sessionhandler.login(caller, new_player)
            else:
                caller.msg({'is_create': True, 'data':
                            {'account': playername, 'dbref': new_player.dbref},
                            'is_login': False})


class CmdUnLoginQuitGame(CmdUnconnectedQuit):
    """
    断开链接, 退出当前游戏,并关闭链接
    方法:
        {'cmd': 'quit',
        'args': ''}
    """
    key = 'quit'
    locks = 'cmd:all()'

    def func(self):
        caller = self.caller
        caller.sessionhandler.disconnect(caller, '关闭链接')
        caller.msg({'is_loginout': True, 'msg': '已经关闭链接'})


class CmdUnLoginLook(CmdUnconnectedLook):
    """
    在未登入的状态下,使用<look>命令, 重新查看屏幕显示的字段
    方法:
        {'cmd': 'look',
         'args': '**'
        }
    """

    key = 'look'
    locks = 'cmd:all()'

    def func(self):
        connection_screen = GAME_SETTINGS.get('connection_screen')

        if not connection_screen:
            connection_screen = '未找到为登入用户首页字段, 请联系管理员'
        self.caller.msg({'is_login': False, 'connection_screen': connection_screen})
